package wcg;

import ikelib.ChannelData;
import ikelib.SecondBlock;
import ikelib.wintime;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet;


/**
 * WINのコンバータ　
 * Asciiファイル ：　拡張子が4ケタのWIN CH IDとしてCH毎に1行1サンプルデータのアスキーファイルに出力する
 * @author ikeda
 *
 */
public class WinExporter {

	private String Infile=null;
	private String OutDir=null;
	private int InfileLength=0;
	private byte[] InfileData=null;
	// 時刻のコレクション
	private TreeSet<wintime> WinTimeValue = new TreeSet<wintime>(); 
	// 秒チャンクのコレクション
	private TreeMap<Integer,byte[]> SecChunk = new TreeMap<Integer,byte[]>();
	private TreeSet<Integer> ChannelId = new TreeSet<Integer>();
	
	WinExporter(){
	}
	
	public String getOutDir() {
		return OutDir;
	}

	public void setOutDir(String outDir) {
		OutDir = outDir;
	}
	// ---------------------------------------------------------------
	// ----- 秒チャンクを読み込む
	// 4:length　含む
	//  :1秒分のデータ
	//  : 
	private void putSecChunk(byte[] data){
		SecondBlock blk;
		for(int offset=0;offset<InfileData.length;offset += blk.length()){
			blk = new SecondBlock(InfileData,offset);
			wintime tm = blk.getWinTime();
			//System.out.println(tm.fmt());
			WinTimeValue.add(tm);

			// チャネルIDのリストを作る
			ArrayList<ChannelData> dat = blk.getChannelDataList();
			for(int i=0;i<dat.size();i++){
				int ch = dat.get(i).getChannelName();
				ChannelId.add(ch);
			}
			
			byte[] chunk = new byte[blk.length()];
			System.arraycopy(InfileData, offset, chunk, 0, blk.length());
			SecChunk.put(tm.getValueS(),chunk);
		}
	}
	
	
	// ----------------------------------------------------
	// ----------------------------------------------------
	public int Convert(String ifile){
		try{
			FileInputStream in = new FileInputStream(ifile);
			InfileLength = in.available();
			InfileData = new byte[InfileLength];
			in.read(InfileData,0,InfileLength);
			in.close();
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
		
		File tmpfile = new File(ifile);
		
		String ifilename = tmpfile.getName();
		
		putSecChunk(InfileData);
		System.out.format("Input file\n%s\n ", ifile);
		Iterator<Integer> ite = ChannelId.iterator();
		int filecount=0;
		// CH ID 毎にループ
		while(ite.hasNext()){
			int count = 0;
			int ch = ite.next();
			//String finename = OutDir + "\\" + ifilename + String.format(".%04X", ch);
			String finename = OutDir + File.separator + ifilename + String.format(".%04X", ch);
			File file = new File(finename);
			PrintWriter pw=null;
			BufferedOutputStream bo=null;
			try {
				if(OutType==0){
					pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
				}
				else if(OutType==1){
					bo =new BufferedOutputStream(new FileOutputStream(finename));
				}
			
				Iterator<wintime> ite2 = WinTimeValue.iterator();
				while(ite2.hasNext()){
					wintime tm = ite2.next();
					byte[] dat = SecChunk.get(tm.getValueS());
					if(dat==null) continue;
					SecondBlock blk = new SecondBlock(dat,0);
					ArrayList<ChannelData> d = blk.getChannelDataList();
					for(int i=0;i<d.size();i++){
						ChannelData cd = d.get(i);
						if(cd.getChannelName() == ch){
							int[] idata = cd.getData();
							for(int j=0;j<idata.length;j++){
								if(OutType==0){
									pw.println(idata[j]);
								}
								else if(OutType==1){
									ByteBuffer byteBuf = ByteBuffer.allocate(4);
									if(BigEndian) 	byteBuf.order(ByteOrder.BIG_ENDIAN);
									else			byteBuf.order(ByteOrder.LITTLE_ENDIAN);
									byteBuf.putInt(idata[j]);
									bo.write(byteBuf.array());
								}
								count++;
							}
						}
					}
				}
				if(OutType==0){
					pw.close();
					System.out.format("%s  (ascii) %d line\n ", finename,count);
				}
				else if(OutType==1){
					bo.close();
					System.out.format("%s  (binary) %d x4 byte\n ", finename,count);
				}
				
				filecount++;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.format("%d files created\n\n ", filecount);
		return 0;
	}
	public void clear(){
		WinTimeValue.clear();
		SecChunk.clear();
		ChannelId.clear();
	}
	private int OutType=0;
	private boolean BigEndian = true;
	/**
	 * 0: Ascii 1:Binary(4byte,machine dependent )
	 * @param n
	 */
	public void setOutType(int n) {
		OutType=n;
		
	}
	public void setBigEndian(boolean b) {
		BigEndian=b;
		
	}
}
